package cn.com.blueInfo.autoCode.database;

import cn.com.blueInfo.bpm.system.entity.Menu;
import cn.com.blueInfo.bpm.system.enums.MenuType;
import cn.com.blueInfo.bpm.system.mapper.MenuMapper;
import cn.com.blueInfo.core.util.SnowflakeIdGenerator;
import com.alibaba.fastjson.JSON;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.*;

@Log4j2
@Component
public class CreateMenuDefaultData {

    // 常量定义：提取魔法值，便于统一维护
    private static final String ICON = "Location";
    private static final MenuType MENU_TYPE = MenuType.SYSTEM_MENU;
    private static final String SCHEMA_NAME = "haiyuan_dev";
    private static final String TABLE_NAME_SPLITTER = "_";
    private static final String ROUTE_PATH_PREFIX = "/home/";
    private static final String COMPONENT_PREFIX = "views/bpm/";
    private static final String TABLE_COMMENT_SUFFIX = "表";

    // modelName映射关系：用Map替代switch，更简洁且易于扩展
    private static final Map<String, String> MODEL_NAME_MAPPING = new HashMap<String, String>() {{
        put("sys", "system");
        put("osm", "person");
        put("bsn", "number");
        put("uniflow", "template");
    }};

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private SnowflakeIdGenerator snowflakeIdGenerator;

    @Autowired
    private MenuMapper mapper;

    private List<Menu> menuList;  // 顶级菜单列表
    private List<String> modelNameList;  // 模块名称列表
    private Map<String, Long> modelToTopMenuId;  // 模块名→顶级菜单ID的映射（用于O(1)查询）

    public void handler(Map<String, Long> commonData) {
        // 1. 查询表元数据（表名和表注释）
        List<Map<String, Object>> tableMetaList = queryTableMetadata();
        if (CollectionUtils.isEmpty(tableMetaList)) {
            log.info("未查询到任何表数据，无需生成菜单");
            return;
        }

        // 2. 提取模块名称并创建顶级菜单
        setModelNameList(tableMetaList);
        setMenuListAndMapping(commonData);  // 同时构建顶级菜单ID映射

        // 3. 为每个表生成对应的子菜单
        List<Menu> subMenuList = generateSubMenus(tableMetaList, commonData);

        menuList.addAll(subMenuList);

        // 4. 输出结果（使用日志框架）
        log.info("生成的子菜单列表：{}", JSON.toJSONString(menuList));

        mapper.insert(menuList);
    }

    /**
     * 查询数据库表元数据（表名和表注释）
     */
    private List<Map<String, Object>> queryTableMetadata() {
        String sql = "select table_name, table_comment from information_schema.`TABLES` where TABLE_SCHEMA = ?";
        return jdbcTemplate.queryForList(sql, SCHEMA_NAME);
    }

    /**
     * 提取模块名称列表
     */
    private void setModelNameList(List<Map<String, Object>> tableMetaList) {
        Set<String> modelNameSet = new HashSet<>();  // 用Set自动去重

        for (Map<String, Object> tableMeta : tableMetaList) {
            String tableName = getStringValue(tableMeta, "table_name");
            if (StringUtils.isEmpty(tableName)) {
                continue;
            }

            // 解析表名获取模块原始名称（如sys、osm）
            String[] nameParts = tableName.split(TABLE_NAME_SPLITTER);
            if (nameParts.length < 2) {
                log.warn("表名[{}]格式不符合规范，无法提取模块名称", tableName);
                continue;
            }

            String originalModelName = nameParts[1];
            String mappedModelName = MODEL_NAME_MAPPING.get(originalModelName);
            if (StringUtils.isNotEmpty(mappedModelName)) {
                modelNameSet.add(mappedModelName);
            }
        }

        this.modelNameList = new ArrayList<>(modelNameSet);
    }

    /**
     * 创建顶级菜单并构建模块名→顶级菜单ID的映射
     */
    private void setMenuListAndMapping(Map<String, Long> commonData) {
        this.menuList = new ArrayList<>();
        this.modelToTopMenuId = new HashMap<>();

        if (CollectionUtils.isEmpty(modelNameList)) {
            log.warn("未提取到任何模块名称，不生成顶级菜单");
            return;
        }

        for (String modelName : modelNameList) {
            Menu topMenu = new Menu();
            topMenu.setId(snowflakeIdGenerator.nextId());
            topMenu.setParentId(-1L);
            topMenu.setMenuType(MENU_TYPE);
            topMenu.setMenuName(getTopMenuName(modelName));  // 顶级菜单名称
            topMenu.setRoutePath(ROUTE_PATH_PREFIX + modelName);
            topMenu.setComponent("components/common/BaseBreadcrumb");
            topMenu.setIcon(ICON);
            topMenu.setTenantId(commonData.get("tenantId"));
            topMenu.setApplicationId(commonData.get("applicationId"));
            topMenu.setCreateUserId(commonData.get("createUserId"));

            menuList.add(topMenu);
            modelToTopMenuId.put(modelName, topMenu.getId());  // 缓存映射关系
        }
    }

    /**
     * 为每个表生成子菜单
     */
    private List<Menu> generateSubMenus(List<Map<String, Object>> tableMetaList, Map<String, Long> commonData) {
        List<Menu> subMenuList = new ArrayList<>();

        for (Map<String, Object> tableMeta : tableMetaList) {
            String tableName = getStringValue(tableMeta, "table_name");
            String tableComment = getStringValue(tableMeta, "table_comment");

            if (StringUtils.isEmpty(tableName) || StringUtils.isEmpty(tableComment)) {
                log.warn("表名或表注释为空，跳过该表：{}", tableMeta);
                continue;
            }

            // 解析表名获取模块参数和菜单路径
            String modelNameParam = extractModelNameParam(tableName);
            if (StringUtils.isEmpty(modelNameParam)) {
                log.warn("表名[{}]无法解析出模块参数，跳过", tableName);
                continue;
            }

            // 获取父菜单ID（顶级菜单ID）
            Long parentId = modelToTopMenuId.get(modelNameParam);
            if (parentId == null) {
                log.warn("模块[{}]未找到对应的顶级菜单，跳过表[{}]", modelNameParam, tableName);
                continue;
            }

            // 构建子菜单对象
            Menu subMenu = new Menu();
            subMenu.setId(snowflakeIdGenerator.nextId());
            subMenu.setParentId(parentId);
            subMenu.setMenuType(MENU_TYPE);
            subMenu.setIcon(ICON);
            subMenu.setMenuName(processMenuName(tableComment));  // 处理表注释为菜单名
            subMenu.setRoutePath(generateRoutePath(modelNameParam, tableName));  // 生成路由路径
            subMenu.setComponent(generateComponentPath(modelNameParam, tableName));  // 生成组件路径
            subMenu.setTenantId(commonData.get("tenantId"));
            subMenu.setApplicationId(commonData.get("applicationId"));
            subMenu.setCreateUserId(commonData.get("createUserId"));

            subMenuList.add(subMenu);
        }

        return subMenuList;
    }

    /**
     * 从表名中提取模块参数（如system、person）
     */
    private String extractModelNameParam(String tableName) {
        String[] nameParts = tableName.split(TABLE_NAME_SPLITTER);
        if (nameParts.length < 2) {
            return null;
        }
        return MODEL_NAME_MAPPING.get(nameParts[1]);  // 直接从映射表获取
    }

    /**
     * 处理表注释生成菜单名（移除末尾的"表"字）
     */
    private String processMenuName(String tableComment) {
        if (tableComment.endsWith(TABLE_COMMENT_SUFFIX)) {
            return tableComment.substring(0, tableComment.length() - 1);
        }
        return tableComment;
    }

    /**
     * 生成路由路径（如/home/system/User）
     */
    private String generateRoutePath(String modelNameParam, String tableName) {
        String menuPath = generateMenuPath(tableName);
        return ROUTE_PATH_PREFIX + modelNameParam + "/" + menuPath;
    }

    /**
     * 生成组件路径（如view/bpm/system/User）
     */
    private String generateComponentPath(String modelNameParam, String tableName) {
        String menuPath = generateMenuPath(tableName);
        return COMPONENT_PREFIX + modelNameParam + "/" + menuPath + "/index";
    }

    /**
     * 生成菜单路径（如表名sys_user→User）
     */
    private String generateMenuPath(String tableName) {
        String[] nameParts = tableName.split(TABLE_NAME_SPLITTER);
        String menuPath = "";

        // 从第3部分开始拼接（前两部分是前缀和模块名）
        for (int i = 2; i < nameParts.length; i++) {
            String part = nameParts[i];
            menuPath = menuPath.concat(StringUtils.capitalize(part));
        }
        menuPath = StringUtils.uncapitalize(menuPath);
        return menuPath;
    }

    /**
     * 获取顶级菜单名称
     */
    private String getTopMenuName(String modelName) {
        switch (modelName) {
            case "system":
                return "系统模块";
            case "person":
                return "人员组织模块";
            case "number":
                return "编码模块";
            case "template":
                return "流程模板模块";
            default:
                return modelName + "模块";  // 默认名称，避免遗漏
        }
    }

    /**
     * 安全获取Map中的字符串值（处理null）
     */
    private String getStringValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        return value == null ? null : value.toString();
    }

}
